package contents;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.sql.SQLException;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import database.Database;
import contents.entities.Message;
import database.DatabaseEntities;
import java.util.Collections;

public class MessagesContent {
    
    public static HttpServletRequest checkForNewMessages(HttpServletRequest request) throws SQLException {
        HttpSession session = request.getSession();
        
        String userRole = (String) session.getAttribute("userRole");
        int userId;
        if (!userRole.equals("admin")) {
            userId = ((Integer) session.getAttribute("userId")).intValue();
        } else {
            userId = -1;
        }
        
        Database.UserRole role;
        if (userRole.equals("student")) {
            role = Database.UserRole.STUDENT;
        } else if (userRole.equals("teacher")) {
            role = Database.UserRole.TEACHER;
        } else if (userRole.equals("parent")) {
            role = Database.UserRole.PARENT;
        } else {
            // ADMIN
            role = Database.UserRole.ADMIN;
        }
        
        if (Database.userHasUnseenMessages(userId, role)) {
            request.setAttribute("newMessages", "true");
        } else {
            request.setAttribute("newMessages", "false");
        }
        return request;
    }
    
    public static HttpServletRequest setMessageBoxContent(HttpServletRequest request) throws SQLException {
        HttpSession session = request.getSession();
        String userRole = (String) session.getAttribute("userRole");
        
        String username;
        if (userRole.equals("student")) {
            int userId = ((Integer) session.getAttribute("userId")).intValue();
            username = Database.selectUsernameOfUser(Database.UserRole.STUDENT, userId);
        } else if (userRole.equals("parent")) {
            int userId = ((Integer) session.getAttribute("userId")).intValue();
            username = Database.selectUsernameOfUser(Database.UserRole.PARENT, userId);
        } else if (userRole.equals("teacher")) {
            int userId = ((Integer) session.getAttribute("userId")).intValue();
            username = Database.selectUsernameOfUser(Database.UserRole.TEACHER, userId);
        } else {
            username = Database.selectUsernameOfUser(Database.UserRole.ADMIN, -1);
        }
        
        // set all messages of user as read
        Database.setMessagesOfUserAsSeen(username);
        request.setAttribute("newMessages", "false");
        
        // get list of messages
        List<database.DatabaseEntities.Message> databaseMessages = Database.getMessagesOfUser(username);
        
        List<Message> messages = new ArrayList<Message>();
        for (int i = 0; i < databaseMessages.size(); i++) {
            int messageId = databaseMessages.get(i).messageId;
            String text = databaseMessages.get(i).text;
            
            String origin;
            if (databaseMessages.get(i).sender == database.DatabaseEntities.Message.Sender.ME) {
                origin = "sent_message";
            } else {
                origin = "received_message";
            }
            
            int remotePeerId = databaseMessages.get(i).remotePeerId;
            String remotePeerRole = databaseMessages.get(i).remotePeerRole;
            String remotePeerFirstName = databaseMessages.get(i).remotePeerFirstName;
            String remotePeerLastName = databaseMessages.get(i).remotePeerLastName;
            
            String timedate = databaseMessages.get(i).timestamp;

            String dateString, timeString;
            try {
                java.text.SimpleDateFormat datetimeFormat = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                java.util.Date date = datetimeFormat.parse(timedate);
                
                java.text.SimpleDateFormat dateFormat = new java.text.SimpleDateFormat("dd.MM.yyyy");
                dateString = dateFormat.format(date);
                java.text.SimpleDateFormat timeFormat = new java.text.SimpleDateFormat("HH:mm:ss");
                timeString = timeFormat.format(date);
            } catch (java.text.ParseException exception) {
                // this should not happen
                dateString = "";
                timeString = "";
            }
            
            messages.add(new Message(messageId, origin, remotePeerId, remotePeerRole, remotePeerFirstName, 
                                     remotePeerLastName, text, dateString, timeString));
        }
        
        // sort messages
        String sortType = request.getParameter("sort");        
        if (sortType == null || sortType.equals("byDate")) {
            Collections.sort(messages, new Message.ByDateComparator());
        } else if (sortType.equals("alphabetically")) {
            Collections.sort(messages, new Message.ByPeerAlphabeticallyComparator());
            // insert null messages to indicate to jsp that there is hr
            
            if (messages.size() != 0) {
                String lastName1 = messages.get(0).getRemotePeerLastName();
                String firstName1 = messages.get(0).getRemotePeerFirstName();
                String role1 = messages.get(0).getRemotePeerRole();
                Integer id1 = messages.get(0).getRemotePeerId();
                
                String lastName2, firstName2, role2;
                Integer id2;
                
                for (int i = 1; i < messages.size(); i++) {
                    lastName2 = messages.get(i).getRemotePeerLastName();
                    firstName2 = messages.get(i).getRemotePeerFirstName();
                    role2 = messages.get(i).getRemotePeerRole();
                    id2 = messages.get(i).getRemotePeerId();
                    
                    if (!lastName1.equals(lastName2) || !firstName1.equals(firstName2) || !role1.equals(role2)
                            || !id1.equals(id2)) {
                        // insert between conversations with 2 different peers null message
                        messages.add(i, null);
                        i++;
                    }
                    
                    lastName1 = lastName2;
                    firstName1 = firstName2;
                    role1 = role2;
                    id1 = id2;
                }
            }
        }
        
        // put messages to request
        Map<Integer, Message> messagesMap = new HashMap<Integer, Message>();

        for (int i = 0; i < messages.size(); i++) {
            messagesMap.put(i, messages.get(i));
        }

        request.setAttribute("messages", messagesMap.values());
        return request;
    }
    
    public static boolean deleteMessage(HttpServletRequest request) throws SQLException {
        int messageId = Integer.valueOf(request.getParameter("messageId")).intValue();
        
        HttpSession session = request.getSession();
        String userRole = (String) session.getAttribute("userRole");
        
        String username;
        if (userRole.equals("visitor")) {
            return false;
        } else if (userRole.equals("student")) {
            int userId = ((Integer) session.getAttribute("userId")).intValue();
            username = Database.selectUsernameOfUser(Database.UserRole.STUDENT, userId);
        } else if (userRole.equals("parent")) {
            int userId = ((Integer) session.getAttribute("userId")).intValue();
            username = Database.selectUsernameOfUser(Database.UserRole.PARENT, userId);
        } else if (userRole.equals("teacher")) {
            int userId = ((Integer) session.getAttribute("userId")).intValue();
            username = Database.selectUsernameOfUser(Database.UserRole.TEACHER, userId);
        } else {
            //ADMIN
            username = Database.selectUsernameOfUser(Database.UserRole.ADMIN, -1);
        }
        
        return Database.deleteMessageOfUsername(messageId, username);
    }
    
    public static HttpServletRequest setNewMessageContent(HttpServletRequest request) throws SQLException {
        String remotePeerUserRole = request.getParameter("userRole");
        int remotePeerUserId = Integer.parseInt(request.getParameter("userId")) ;
        
        String remotePeerName;
        if (remotePeerUserRole.equals("admin")) {
            remotePeerName = "Administrátor";
        } else if (remotePeerUserRole.equals("student")) {
            DatabaseEntities.Student student = Database.selectNameClassIdAndClassNameOfStudent(remotePeerUserId);
            remotePeerName = student.name;
        } else if (remotePeerUserRole.equals("parent")) {
            DatabaseEntities.Parent parent = Database.selectNameStudentNameClassIdAndClassNameOfParent(remotePeerUserId);
            remotePeerName = parent.name;
        } else if (remotePeerUserRole.equals("teacher")) {
            DatabaseEntities.Teacher teacher = Database.selectNameOfTeacher(remotePeerUserId);
            remotePeerName = teacher.name;
        } else {
            throw new IllegalArgumentException("setNewMessageContent: Can not write message to visitor.");
        }
        request.setAttribute("userName", remotePeerName);

        return request;
    }
    
    public static boolean sendMessage(HttpServletRequest request) throws SQLException {
        String remotePeerUserRole = request.getParameter("userRole");
        int remotePeerUserId = Integer.parseInt(request.getParameter("userId"));
        
        String remotePeerUsername;
        if (remotePeerUserRole.equals("admin")) {
            remotePeerUsername = Database.selectUsernameOfUser(Database.UserRole.ADMIN, remotePeerUserId);
        } else if (remotePeerUserRole.equals("student")) {
            remotePeerUsername = Database.selectUsernameOfUser(Database.UserRole.STUDENT, remotePeerUserId);
        } else if (remotePeerUserRole.equals("parent")) {
            remotePeerUsername = Database.selectUsernameOfUser(Database.UserRole.PARENT, remotePeerUserId);
        } else if (remotePeerUserRole.equals("teacher")) {
            remotePeerUsername = Database.selectUsernameOfUser(Database.UserRole.TEACHER, remotePeerUserId);
        } else {
            return false;
        }
        
        HttpSession session = request.getSession();
        String localPeerUserRole = (String) session.getAttribute("userRole");
        String localPeerUsername;
        if (localPeerUserRole.equals("student")) {
            int localPeerUserId = ((Integer) session.getAttribute("userId")).intValue();
            localPeerUsername = Database.selectUsernameOfUser(Database.UserRole.STUDENT, localPeerUserId);
        } else if (localPeerUserRole.equals("parent")) {
            int localPeerUserId = ((Integer) session.getAttribute("userId")).intValue();
            localPeerUsername = Database.selectUsernameOfUser(Database.UserRole.PARENT, localPeerUserId);
        } else if (localPeerUserRole.equals("teacher")) {
            int localPeerUserId = ((Integer) session.getAttribute("userId")).intValue();
            localPeerUsername = Database.selectUsernameOfUser(Database.UserRole.TEACHER, localPeerUserId);
        } else {
            // ADMIN
            localPeerUsername = Database.selectUsernameOfUser(Database.UserRole.ADMIN, -1);
        }
        
        String messageText = (String) request.getParameter("text");
        
        if (localPeerUsername.equals(remotePeerUsername)) {
            return false;
        }
        
        Database.insertNewMessage(localPeerUsername, remotePeerUsername, messageText);
        return true;
    }
    
    private MessagesContent() {
    }
}
